import type {
  CascaderOption,
  FormItemRule,
  SelectGroupOption,
  SelectOption,
  EllipsisProps,
} from "naive-ui";
import type { Dic, PrefixRecord, RowData, StringKeys } from "@/_interface";
import type { Placement } from "@/_constant";
import { HTMLAttributes, VNode, VNodeChild } from "vue";
import {
  OnUpdateValue as OnUpdateOfSelect,
  SelectBaseOption,
} from "naive-ui/es/select/src/interface";
import { OnUpdateValue as OnUpdateOfCascader } from "naive-ui/es/cascader/src/interface";
import { CommonColumnInfo } from "naive-ui/es/data-table/src/interface";

type BaseForm = {
  /** 表单默认值 */
  value?: any;
  /** 表单校验规则 */
  rules?: FormItemRule | FormItemRule[];
  /** 表单标签 */
  label?: string;
  /** 表单占位符 */
  placeholder?: string;
  /** 是否禁用表单，默认false */
  disabled?: boolean;
  /** 表单排序，越大排在后面 */
  order?: number;
};

type BaseColumn<T = RowData> = CommonColumnInfo<T> & {
  title: string;
  key: StringKeys<T>;
  titleRowSpan?: number;
  resizable?: boolean;

  render?: (rowData: T, rowIndex: number) => VNodeChild;
  renderTitle?: () => VNodeChild;
  rowSpan?: (rowData: T, rowIndex: number) => number;
  colSpan?: (rowData: T, rowIndex: number) => number;

  /** 列隐藏 */
  hidden?: boolean;
  /** 表单展示，默认true */
  form?: boolean;
  /** 搜索展示，默认false */
  search?: boolean;
} & BaseForm &
  PrefixRecord<"search", BaseForm>;

type InputForm = {
  autofocus?: boolean;
  autosize?: boolean | { minRows?: number; maxRows?: number };
  clearable?: boolean;
  maxlength?: number;
  minlength?: number;
  readonly?: boolean;
  round?: boolean;
  rows?: number;
  showCount?: boolean;
  type?: "input" | "textarea" | "password";
  allowInput?: (val: string) => boolean;
  onInput?: (val: string) => void;
  onBlur?: () => void;
  onFocus?: () => void;
  onClear?: () => void;
  onUpdate?: (val: string) => void;
};

type NumberForm = {
  type: "number";
  clearable?: boolean;
  min?: number;
  max?: number;
  readonly?: boolean;
  precision?: number;
  showButton?: boolean;
  controls?: boolean;
  step?: number;
  buttonPlacement?: "top" | "right";
  keyboard?: { ArrowUp?: boolean; ArrowDown?: boolean };
  format?: (value: number | null) => string;
  parse?: (input: string) => number | null;
  onBlur?: (event: FocusEvent) => void;
  onFocus?: (event: FocusEvent) => void;
  onClear?: () => void;
  onUpdate?: (val: number | null) => void;
};

type RadioForm = {
  type: "radio";
  name?: string;
  /** 是否为按钮组 */
  button?: boolean;
  onUpdate?: (val: string & number & boolean) => void;
} & Dic<{
  label: string;
  value: string | number | boolean;
  disabled?: boolean;
}>;

type CheckboxForm = {
  type: "checkbox";
  max?: number;
  min?: number;
  onUpdate?: (
    value: (string | number)[],
    meta: {
      actionType: "check" | "uncheck";
      value: string | number;
    }
  ) => void;
} & Dic<{
  label: string;
  value: string | number | boolean;
  disabled?: boolean;
}>;

type SwitchForm = {
  type: "switch";
  checkedValue?: string | boolean | number;
  unceheckedValue?: string | boolean | number;
  loading?: boolean;
  round?: boolean;
  rubberBand?: boolean;
  renderIcon?: () => VNodeChild;
  renderChecked?: () => VNodeChild;
  renderCheckedIcon?: () => VNodeChild;
  renderUnchecked?: () => VNodeChild;
  renderUncheckedIcon?: () => VNodeChild;
  onUpdate?: (val: boolean) => void;
};

type SelectForm = {
  type: "select";
  multiple?: boolean;
  clearable?: boolean;
  filterable?: boolean;
  keyboard?: boolean;
  maxTagCount?: number | "responsive";
  placement?: Placement;
  tag?: boolean;
  filter?: (pattern: string, option: object) => boolean;
  renderLabel?: (
    option: SelectOption & SelectGroupOption,
    selected: boolean
  ) => VNodeChild;
  renderOption?: (info: {
    node: VNode;
    option: SelectOption & SelectGroupOption;
    selected: boolean;
  }) => VNodeChild;
  renderTag?: (props: {
    option: SelectBaseOption;
    handleClose: () => void;
  }) => VNodeChild;
  onBlur?: () => void;
  onFocus?: () => void;
  onClear?: () => void;
  onUpdate?: OnUpdateOfSelect;
  onUpdateShow?: (show: boolean) => void;
  onCreate?: (label: string) => SelectOption;
  onSearch?: (value: string) => void;
} & Dic<SelectOption | SelectGroupOption>;

type CascaderForm = {
  type: "cascader";
  multiple?: boolean;
  cascade?: boolean;
  checkStrategy?: "all" | "parent" | "child";
  clearable?: boolean;
  expandTrigger?: "click" | "hover";
  filterable?: boolean;
  maxTagCount?: number | "responsive";
  placement?: Placement;
  separator?: string;
  showPath?: boolean;
  filter?: (
    pattern: string,
    option: CascaderOption,
    path: CascaderOption[]
  ) => boolean;
  renderPrefix?: (info: {
    option: CascaderOption;
    node: VNode | null;
    checked: boolean;
  }) => VNodeChild;
  renderLabel?: (option: CascaderOption, checked: boolean) => VNodeChild;
  renderSuffix?: (info: {
    option: CascaderOption;
    checked: boolean;
  }) => VNodeChild;
  onBlur?: () => void;
  onFocus?: () => void;
  onLoad?: (option: CascaderOption) => Promise<void>;
  onUpdate?: OnUpdateOfCascader;
} & Dic<CascaderOption>;

type DetailForm =
  | InputForm
  | NumberForm
  | RadioForm
  | CheckboxForm
  | SwitchForm
  | SelectForm
  | CascaderForm;

type DetailSearchForm = PrefixRecord<"search", DetailForm>;

export type NaiveCrudColumn<T = RowData> = BaseColumn<T> &
  DetailForm &
  DetailSearchForm;

export interface NaiveCrudOption<T = RowData> {
  select?: "multiple" | "single";
  selectWidth?: number | string;
  selectFixed?: boolean;
  columns: NaiveCrudColumn<T>[];
}

const column: NaiveCrudColumn<{ a: number; b: string }>[] = [
  {
    title: "序号",
    key: "a",
    type: "select",
    dicData: [],
    onUpdate: (val) => {
      console.log(val);
    },
  },
  // title: "序号",
  // key: "no",
  // type: "input",
  // dicData: [],
  // hidden: true,
  // dicUrl: "",
];
